package com.plian.system.service.im.impl;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.plian.Tools.BigDecimalUtil;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.StringPool;
import com.plian.system.bean.im.StakeInvestmentPlanExcelBean;
import com.plian.system.entity.im.BaseInvestmentPlan;
import com.plian.system.entity.im.EffectiveInvestment;
import com.plian.system.entity.im.ProjectInfo;
import com.plian.system.entity.im.StakeInvestmentPlan;
import com.plian.system.mapper.im.*;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.service.im.IStakeInvestmentPlanService;
import com.plian.system.vo.im.StakeInvestmentPlanVO;
import com.plian.system.wrapper.im.StakeInvestmentPlanWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author
 * @since 2019-09-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class StakeInvestmentPlanServiceImpl extends BaseServiceImpl<StakeInvestmentPlanMapper, StakeInvestmentPlan> implements IStakeInvestmentPlanService {

	private StakeInvestmentPlanWrapper stakeInvestmentPlanWrapper;

	private ProjectInfoMapper projectInfoMapper;

	private BaseInvestmentPlanMapper baseInvestmentPlanMapper;

	private EffectiveInvestmentMapper effectiveInvestmentMapper;

	private ExecutionProjectSituationMapper executionProjectSituationMapper;

	@Override
	public boolean saveOrUpdate(StakeInvestmentPlan stakeInvestmentPlan) {
		return super.saveOrUpdate(stakeInvestmentPlan);
	}

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public boolean deleteLogic(List<Long> ids) {
		for (Long id : ids) {
			StakeInvestmentPlan stakeInvestmentPlan = getById(id);
			if (stakeInvestmentPlan == null) {
				return false;
			}
		}
		return super.deleteLogic(ids);
	}

	@Override
	public void write(List<StakeInvestmentPlan> stakeInvestmentPlans, ExcelWriter excelWriter, WriteSheet writeSheet, FillConfig fillConfig){

		/**
		 * 合计
		 */
		StakeInvestmentPlanExcelBean total = StakeInvestmentPlanExcelBean.builder().beginningInvestedTotal(new BigDecimal(0))
				.beginningInvestedEnterprise(new BigDecimal(0)).planTotalInvestment(new BigDecimal(0))
				.planTotalInvestmentEnterprise(new BigDecimal(0)).planCompleteInvestment(new BigDecimal(0)).planCompleteInvestmentTotal(new BigDecimal(0))
				.build();
		Map<Integer, List<StakeInvestmentPlanVO>> map = stakeInvestmentPlanWrapper.entityToVO(stakeInvestmentPlans)
				.stream().collect(Collectors.groupingBy(StakeInvestmentPlanVO::getProjectCategory));
		for (int i = 1; i < 5; i++) {
			List<StakeInvestmentPlanVO> list = map.get(i);
			StakeInvestmentPlanExcelBean sum = StakeInvestmentPlanExcelBean.builder().build();
			if (CollectionUtil.isNotEmpty(list)) {
				int index = 1;
				for (StakeInvestmentPlanVO vo : list) {
					vo.setIsNewProjectStr(vo.getIsNewProject() == 1 ? "否" : "是");
					vo.setIndex(i + "." + index);
					index++;
					/**
					 * 小计
					 */
					sum.setBeginningInvestedTotal(BigDecimalUtil.add(sum.getBeginningInvestedTotal(), vo.getBeginningInvestedTotal()));
					sum.setBeginningInvestedEnterprise(BigDecimalUtil.add(sum.getBeginningInvestedEnterprise(), vo.getBeginningInvestedEnterprise()));
					sum.setPlanTotalInvestment(BigDecimalUtil.add(sum.getPlanTotalInvestment(), vo.getPlanTotalInvestment()));
					sum.setPlanTotalInvestmentEnterprise(BigDecimalUtil.add(sum.getPlanTotalInvestmentEnterprise(), vo.getPlanTotalInvestmentEnterprise()));
					sum.setPlanCompleteInvestment(BigDecimalUtil.add(sum.getPlanCompleteInvestment(), vo.getPlanCompleteInvestment()));
					sum.setPlanCompleteInvestmentTotal(BigDecimalUtil.add(sum.getPlanCompleteInvestmentTotal(), vo.getPlanCompleteInvestmentTotal()));
				}
				sum.setIndex(i + "." + index);
				/**
				 * 数据填充
				 */
				switch (i){
					case 1:
						excelWriter.fill(toMap("one", sum), fillConfig, writeSheet);
						excelWriter.fill(new FillWrapper("one", list), fillConfig, writeSheet);
						break;
					case 2:
						excelWriter.fill(toMap("two", sum), fillConfig, writeSheet);
						excelWriter.fill(new FillWrapper("two", list), fillConfig, writeSheet);
						break;
					case 3:
						excelWriter.fill(toMap("three", sum), fillConfig, writeSheet);
						excelWriter.fill(new FillWrapper("three", list), fillConfig, writeSheet);
						break;
					case 4:
						excelWriter.fill(toMap("four", sum), fillConfig, writeSheet);
						excelWriter.fill(new FillWrapper("four", list), fillConfig, writeSheet);
						break;
					default:
						break;
				}
			}

			/**
			 * 总计
			 */
			total.setBeginningInvestedTotal(BigDecimalUtil.add(total.getBeginningInvestedTotal(), sum.getBeginningInvestedTotal()));
			total.setBeginningInvestedEnterprise(BigDecimalUtil.add(total.getBeginningInvestedEnterprise(), sum.getBeginningInvestedEnterprise()));
			total.setPlanTotalInvestment(BigDecimalUtil.add(total.getPlanTotalInvestment(), sum.getPlanTotalInvestment()));
			total.setPlanTotalInvestmentEnterprise(BigDecimalUtil.add(total.getPlanTotalInvestmentEnterprise(), sum.getPlanTotalInvestmentEnterprise()));
			total.setPlanCompleteInvestment(BigDecimalUtil.add(total.getPlanCompleteInvestment(), sum.getPlanCompleteInvestment()));
			total.setPlanCompleteInvestmentTotal(BigDecimalUtil.add(total.getPlanCompleteInvestmentTotal(), sum.getPlanCompleteInvestmentTotal()));

		}

		excelWriter.fill(toMap("five", total), fillConfig, writeSheet);
	}

	@Override
	public boolean deleteByBaseId(Long baseInvestmentPlanId) {
		List<StakeInvestmentPlan> stakeInvestmentPlans = list(new LambdaQueryWrapper<StakeInvestmentPlan>()
				.eq(StakeInvestmentPlan::getBaseInvestmentPlanId, baseInvestmentPlanId));
		if (CollectionUtil.isNotEmpty(stakeInvestmentPlans)){
			return deleteLogic(stakeInvestmentPlans.stream().map(StakeInvestmentPlan::getId).collect(Collectors.toList()));
		}
		return true;
	}

	@Override
	public boolean deleteByParentId(List<Long> ids) {
		LambdaQueryWrapper<StakeInvestmentPlan> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(StakeInvestmentPlan::getBaseInvestmentPlanId, ids);
		List<StakeInvestmentPlan> stakeInvestmentPlans = list(queryWrapper);
		if (CollectionUtil.isNotEmpty(stakeInvestmentPlans)){
			return deleteLogic(stakeInvestmentPlans.stream().map(StakeInvestmentPlan::getId).collect(Collectors.toList()));
		}
		return true;
	}

	@Override
	public String checkMsg(List<StakeInvestmentPlan> stakeInvestmentPlanList,int year) {
		StringBuilder msg=new StringBuilder();
		List<Long> projectIds = stakeInvestmentPlanList.stream().map(StakeInvestmentPlan::getProjectId).filter(m -> Optional.ofNullable(m).isPresent()).collect(Collectors.toList());

		List<ProjectInfo> projectInfos = projectInfoMapper.selectBatchIds(projectIds);
		List<StakeInvestmentPlan> stakeInvestmentPlans = list(Wrappers.<StakeInvestmentPlan>lambdaQuery().in(StakeInvestmentPlan::getProjectId, projectIds));
		//去年的所有计划
		int lastYear = year - 1;
		//执行-有效投资
		List<EffectiveInvestment> allEffectiveInvestments = effectiveInvestmentMapper.selectList(Wrappers.<EffectiveInvestment>lambdaQuery().like(EffectiveInvestment::getFilingDate, lastYear));
		if (CollectionUtil.isNotEmpty(allEffectiveInvestments)){

		}
		List<BaseInvestmentPlan> baseInvestmentPlans = new ArrayList<>();
		if (CollectionUtil.isNotEmpty(stakeInvestmentPlans)){
			List<Long> baseInvestmentIds = stakeInvestmentPlans.stream().map(StakeInvestmentPlan::getBaseInvestmentPlanId).collect(Collectors.toList());
			baseInvestmentPlans = baseInvestmentPlanMapper.selectList(Wrappers.<BaseInvestmentPlan>lambdaQuery().eq(BaseInvestmentPlan::getFilingYear,lastYear).in(BaseInvestmentPlan::getId,baseInvestmentIds));
		}

		for(StakeInvestmentPlan stakeInvestmentPlan:stakeInvestmentPlanList){
			StringBuilder str=new StringBuilder();
			String projectName=stakeInvestmentPlan.getProjectName();
			//是否续建项目
			Optional<ProjectInfo> projectOptional = projectInfos.stream().filter(m -> stakeInvestmentPlan.getProjectId().equals(m.getId())).findFirst();
			if (projectOptional.isPresent()){
				ProjectInfo projectInfo = projectOptional.get();
				if (Optional.ofNullable(projectInfo.getProjectStatus()).isPresent() && projectInfo.getProjectStatus() == 1){
					//去年 累计完成投资总额+本年计划投资额=今年 累计完成投资总额
					List<StakeInvestmentPlan> investmentPlans = stakeInvestmentPlans.stream().filter(m -> stakeInvestmentPlan.getProjectId().equals(m.getProjectId())).collect(Collectors.toList());
					if (CollectionUtil.isNotEmpty(investmentPlans)){
						List<Long> baseIds = investmentPlans.stream().map(StakeInvestmentPlan::getBaseInvestmentPlanId).collect(Collectors.toList());
						if (CollectionUtil.isNotEmpty(baseInvestmentPlans)){
							Optional<BaseInvestmentPlan> planOptional = baseInvestmentPlans.stream().filter(m -> baseIds.contains(m.getId())).max(Comparator.comparing(BaseInvestmentPlan::getFilingDate));
							if (planOptional.isPresent()){
								BaseInvestmentPlan baseInvestmentPlan = planOptional.get();
								Optional<StakeInvestmentPlan> investmentPlan = stakeInvestmentPlans.stream().filter(m -> baseInvestmentPlan.getId().equals(m.getBaseInvestmentPlanId()) && stakeInvestmentPlan.getProjectId().equals(m.getProjectId())).findFirst();
								if (investmentPlan.isPresent()){
									StakeInvestmentPlan oldStake = investmentPlan.get();
									//去年累计完成投资总额
									BigDecimal lastTotal = oldStake.getPlanCompleteInvestmentTotal();
									//今年投资额
									BigDecimal completeInvestment = stakeInvestmentPlan.getPlanCompleteInvestment();
									BigDecimal planTotal = lastTotal.add(completeInvestment);
									//本年总额
									BigDecimal planCompleteInvestmentTotal = stakeInvestmentPlan.getPlanCompleteInvestmentTotal();
									if(planTotal.compareTo(planCompleteInvestmentTotal)!=0){
//										str.append("本年计划完成投资  本年投资完成后，累计完成投资总额 ≠ 本年计划完成投资 投资额 + 去年投资完成后，累计完成投资总额").append(StringPool.SEMICOLON);
									}
								}
							}
						}
					}
					//是否本年新增项目为否
					if (Optional.ofNullable(stakeInvestmentPlan.getIsNewProject()).isPresent() && stakeInvestmentPlan.getIsNewProject() != 1){
						str.append("是否本年新增项目应该为否").append(StringPool.SEMICOLON);
					}
				}
			}
			if(str.toString().length()>0){
				str.insert(0,projectName+StringPool.COLON);
			}
			if(str.toString().length()>0){
				msg.append(str);
			}
		}
		return msg.toString();
	}

	private Map<String, Object> toMap(String str, StakeInvestmentPlanExcelBean bean){
		Map<String, Object> map = new HashMap<>(16);
		map.put(str + "StakeIndex", bean.getIndex());
		map.put(str + "BeginningInvestedTotal",bean.getBeginningInvestedTotal());
		map.put(str + "BeginningInvestedEnterprise",bean.getBeginningInvestedEnterprise());
		map.put(str + "BeginningInvestedStake",bean.getBeginningInvestedStake());
		map.put(str + "PlanTotalInvestment",bean.getPlanTotalInvestment());
		map.put(str + "PlanTotalInvestmentEnterprise",bean.getPlanTotalInvestmentEnterprise());
		map.put(str + "PlanCompleteInvestment",bean.getPlanCompleteInvestment());
		map.put(str + "PlanCompleteInvestmentTotal",bean.getPlanCompleteInvestmentTotal());
		return map;
	 }


}
